package com.example.first.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author LSQ
 * @Description 实践证明多线程共享对象会发生线程不安全的问题
 * @date 2021/8/6 16:42
 * @Version 1.0
 */

class Person2 {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class LearnThreadLocal2 {

    private static final int ARRAY_BLOCKING_QUEUE_CAPACITY = 1000;
    private static final int COOL_POOL_SIZE = 100;
    private static final int MAXIMUM_POOL_SIZE = 100;
    private static final int KEEP_ALIVE_TIME = 60;
    private static final int TASK_NUMBER = 500;

    public static void main(String[] args) {
        ExecutorService executorService = new ThreadPoolExecutor(COOL_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(ARRAY_BLOCKING_QUEUE_CAPACITY));
        Person2 person2 = new Person2();
        for (int i = 0; i < TASK_NUMBER; i++) {
            String myName = "lsq" + i;
            Runnable runnable = () -> {
                person2.setName(myName);
                System.out.printf("Task [ %s ] print person name: %s \n", Thread.currentThread().getName(), person2.getName());

            };
            executorService.submit(runnable);

        }


    }
}


/*
ThreadLocal 的目的是让每个线程都生成一个实例的副本

1、如果没有用ThreadLocal，可能会发现线程不安全的问题，上一个线程set的数据，被下一个线程get到了
2、有了ThreadLocal，set的值就会缓存到当前的线程里面

 */